package com.gis.controller;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import com.gis.service.DirectoryMonitorService;
import com.gis.service.LayerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gis.dto.MonitorDirectoryDTO;
import com.gis.entity.LayerData;
import com.gis.entity.MonitorDirectory;
import com.gis.result.ResponseResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;



@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/monitor")
@Tag(name = "监控文件夹", description = "监控数据接口")
public class MonitorController {
    @Autowired
    private DirectoryMonitorService monitorService;

    @Autowired
    private LayerService layerService;

    @Operation(summary = "添加监控目录", description = "添加新的监控目录")
    @PostMapping("/add")
    public ResponseResult<?> add(@RequestBody MonitorDirectoryDTO monitorDirectoryDTO) {
        MonitorDirectory entity = monitorService.addMonitorDirectory(monitorDirectoryDTO);
        return ResponseResult.success("添加成功", entity);
    }

    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除监控目录", description = "根据 ID 删除监控目录")
    public ResponseResult<?> delete(@PathVariable Long id) {
        if (id == null) {
            return ResponseResult.fail("ID不能为空");
        }
        // 查询id是否存在，如果有则删除，没有则报错
        MonitorDirectory directory = monitorService.getById(id);
        if (directory == null) {
            return ResponseResult.fail("ID不存在");
        }
        monitorService.removeById(id);

        return ResponseResult.success("删除成功");
    }

    @Operation(summary = "更新监控目录", description = "根据 ID 更新监控目录")
    @PutMapping("/update/{id}")
    public ResponseResult<?> update(@PathVariable Long id, @RequestBody MonitorDirectoryDTO monitorDirectoryDTO) 
    {
        MonitorDirectory mondir = this.monitorService.getById(id);
        // 如果mondir为null，返回未找到
        if (mondir == null) {
            return ResponseResult.fail("未找到对应的监控目录");
        }
        BeanUtils.copyProperties(monitorDirectoryDTO, mondir);
        this.monitorService.updateById(mondir);
        return ResponseResult.success("更新成功", mondir);
    }

    @Operation(summary = "查询监控目录列表", description = "获取所有监控目录")
    @GetMapping("/list")
    public ResponseResult<?> list() {
        List<MonitorDirectory> directories = monitorService.list();
        return ResponseResult.success(directories);
    }

    
    @Operation(summary = "查询监控目录详情", description = "根据 ID 获取监控目录详情")
    @GetMapping("/detail")
    @Parameters({
        @Parameter(name = "param", description = "监控目录ID", required = true, example = "1")
    })
    public ResponseResult<MonitorDirectory> getMethodName(@RequestParam String param) throws Exception {
        // 判断数据库中是否存在该ID
        MonitorDirectory directory = monitorService.getById(Long.parseLong(param));
        if (directory == null) {
            throw new Exception("未找到对应ID的监控目录");
        }
        return ResponseResult.success(this.monitorService.getById(Long.parseLong(param)));
    }
    
    @Operation(summary = "根据ID(数组)开启监控目录", description = "根据 ID(数组) 开启监控目录")
    @PostMapping("/start")
    public ResponseResult<?> startMonitor(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return ResponseResult.fail("ID列表不能为空");
        }
        for (Long id : ids) {
            Path dirPath = Paths.get(this.monitorService.getById(id).getDirName());
            try{
                this.monitorService.registerAllDirs(dirPath);
            } catch (Exception e) {
                log.error("Error starting monitor for directory ID {}: {}", id, e.getMessage());
                return ResponseResult.fail("开启监控失败: " + e.getMessage());
            }
        }
        return ResponseResult.success("开启监控成功");
    }

    @Operation(summary = "停止监控目录", description = "停止指定的监控目录")
    @PostMapping("/stop")
    public ResponseResult<?> stopMonitor(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return ResponseResult.fail("ID列表不能为空");
        }
        for (Long id : ids) {
            this.monitorService.removeMonitorDirectory(id);
        }
        return ResponseResult.success("停止监控成功");
    }

    @Operation(summary = "上传文件", description = "上传文件到指定的监控目录")
    @PostMapping("/upload")
    @Parameters({
        @Parameter(name = "files", description = "上传的文件", required = true),
        @Parameter(name = "dirId", description = "监控目录ID", required = true)
    })
    public ResponseResult<?> uploadFile(@RequestParam("files") MultipartFile[] file, @RequestParam("dirId") Long dirId) {
        if (file == null || file.length == 0) {
            return ResponseResult.fail("未选择文件");
        }
        MonitorDirectory directory = monitorService.getById(dirId);
        if (directory == null) {
            return ResponseResult.fail("未找到对应的监控目录");
        }
        try {
            for (MultipartFile multipartFile : file) {
                // 检查文件名是否重复
                QueryWrapper<LayerData> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("origin_name", multipartFile.getOriginalFilename());
                if (this.layerService.exists(queryWrapper)) {
                    log.warn("文件名已存在: {}", directory.getDirName());
                    throw new IllegalArgumentException("文件名已存在: " + directory.getDirName());
                }

                if (multipartFile.isEmpty()) {
                    return ResponseResult.fail("文件不能为空");
                }
                // 获取上传文件的原始文件名
                String originalFilename = multipartFile.getOriginalFilename();
                // 构建目标文件路径
                Path targetPath = Paths.get(directory.getDirName(), originalFilename);
                // 保存文件到目标路径
                multipartFile.transferTo(targetPath);
            }
            return ResponseResult.success("文件上传成功");
        } catch (Exception e) {
            log.error("文件上传失败: {}", e.getMessage());
            return ResponseResult.fail("文件上传失败: " + e.getMessage());
        }
    }

    @Operation(summary = "根据目录ID获取文件列表", description = "获取指定监控目录下的文件列表")
    @Parameters({
        @Parameter(name = "id", description = "监控目录ID", required = true, example = "1")
    })
    @GetMapping("/getFilesByDirId")
    public ResponseResult<List<File>> getFilesById(@RequestParam Long id) {
        List<File> files = this.monitorService.getFilesByDirId(id);
        return ResponseResult.success(files);
    }
    
}
